// PCMod Network Tester Tool \\

SWEP.PrintName = "Network Diagnostics Tool"
SWEP.Author = "[GU]|ZLC|thomasfn"
SWEP.Contact = "Don't."
SWEP.Category = "PCMod"
SWEP.Purpose = "To test networks."
SWEP.Instructions = "Left click to select the PCs, right click to choose test mode."

if CLIENT then
	SWEP.Slot 				= 5
	SWEP.DrawAmmo 			= false
	SWEP.DrawCrosshair 		= true
	SWEP.ViewModelFOV		= 70
	SWEP.ViewModelFlip		= false
end

if SERVER then
	AddCSLuaFile("shared.lua")
	SWEP.Weight				= 5
	SWEP.AutoSwitchTo		= true
	SWEP.AutoSwitchFrom		= false
end

SWEP.Spawnable = true
SWEP.AdminSpawnable = true

SWEP.HoldType = "pistol"

SWEP.Primary.Ammo = "none"
SWEP.Primary.ClipSize = -1
SWEP.Primary.DefaultClip = -1
SWEP.Primary.Automatic = false

SWEP.Secondary.Ammo = "none"
SWEP.Secondary.ClipSize = -1
SWEP.Secondary.DefaultClip = -1
SWEP.Secondary.Automatic = false

SWEP.TestModes = {
	"IP Path Find",
	"Packet Delivery",
	"GChat Tester"
}

SWEP.ProgramID = 1

SWEP.ViewModel = "models/weapons/v_c4.mdl"
SWEP.WorldModel = "models/weapons/w_c4.mdl"

if (SERVER) then

	SWEP.TMode = 1
	
	SWEP.Ent1 = nil
	SWEP.Ent2 = nil
	
	function SWEP:Initialize()
		self:SetWeaponHoldType(self.HoldType)
		self:SelectMode( 1 )
	end
	
	function SWEP:Reload()
		// Check if we are looking at an entity
		local trace = {}
		trace.start = self.Owner:EyePos()
		trace.endpos = trace.start + self.Owner:GetAimVector() * 200
		trace.filter = self.Owner
		local tr = util.TraceLine(trace)
		
		// If it is an entity, return its info
		if ((tr.Entity) && (tr.Entity:IsValid())) then
			if (tr.Entity.IsRouter) then
				self:SetNWString( "info", tostring( tr.Entity.Data[ tr.Entity:EntIndex() ].RID ) )
			end
		end
	end
	
	function SWEP:SelectMode( ID )
		self.TMode = ID
		self:SetNWString( "mode", self.TestModes[ ID ] )
	end
	
	function SWEP:Holster()
		self.Ent1 = nil
		self.Ent2 = nil
		return true
	end
	
	function SWEP:PrimaryAttack()
		// Check if we are looking at an entity
		local trace = {}
		trace.start = self.Owner:EyePos()
		trace.endpos = trace.start + self.Owner:GetAimVector() * 200
		trace.filter = self.Owner
		local tr = util.TraceLine(trace)
		
		// Check if that entity is a PC or a server
		if (tr.Entity) then
			if ((tr.Entity.IsPC) || (tr.Entity.IsServer)) then
				// Get our ent
				ent = tr.Entity
				entid = ent:EntIndex()
				
				// Check for a glitch
				if ((self.Ent1) && (self.Ent2)) then
					self.Ent1 = nil
					self.Ent2 = nil
				end
				
				// Select it
				if (!self.Ent1) then
					self.Ent1 = ent
					self.Owner:PrintMessage( HUD_PRINTTALK, "PC Selected" )
					return true
				end
				
				// Do stuff with it
				if (!self.Ent2) then
					self.Ent2 = ent
					self:DoAction()
					self.Ent1 = nil
					self.Ent2 = nil
					return true
				end
			end
		end
		
		// We were successful
		return true
	end
	
	function SWEP:DoAction()
		local ply = self.Owner
		if (self.TMode == 1) then
			// IP Lookup
			local router = self.Ent1.Data[ self.Ent1:EntIndex() ].Router
			if (!router) then return end
			local target = self.Ent2.Data[ self.Ent2:EntIndex() ].IP
			local result = router:LookForIP( target )
			if (result) then
				ply:PrintMessage( HUD_PRINTTALK, "Path was found!" )
			else
				ply:PrintMessage( HUD_PRINTTALK, "Path was NOT found!" )
			end
			// Print out the path
			self:PrintPath( PacketPath )
			// Has the IP Lookup function is designed for internal use, we have to clean up after it
			PacketPath = {}
		end
		if (self.TMode == 2) then
			// Pinger
			local router = self.Ent1.Data[ self.Ent1:EntIndex() ].Router
			if (!router) then return end
			local target = self.Ent2.Data[ self.Ent2:EntIndex() ].IP
			local source = self.Ent1.Data[ self.Ent1:EntIndex() ].IP
			local packet = { source, target, 50, { "ping" } }
			local result = self.Ent1:SendPacket( packet )
			ply:PrintMessage( HUD_PRINTTALK, DeliveryStatus( result ) )
		end
		if (self.TMode == 3) then
			// GChat
			local router = self.Ent1.Data[ self.Ent1:EntIndex() ].Router
			if (!router) then return end
			local target = self.Ent2.Data[ self.Ent2:EntIndex() ].IP
			local source = self.Ent1.Data[ self.Ent1:EntIndex() ].IP
			local packet = { source, target, 18, { "svr_gchat_message", "[Network Test Packet]" } }
			local result = self.Ent1:SendPacket( packet )
			ply:PrintMessage( HUD_PRINTTALK, DeliveryStatus( result ) )
		end
	end
	
	function SWEP:SecondaryAttack()
		// Change to next mode
		local newid = self.TMode + 1
		if (newid > #self.TestModes) then newid = 1 end
		self:SelectMode( newid )
	end
	
	function SWEP:PrintPath( path )
		for x=1,#path do
			local txt = "NODE->" .. tostring( path[x].Data[ path[x]:EntIndex() ].RID )
			self.Owner:PrintMessage( HUD_PRINTTALK, txt )
		end
	end
	
	function SWEP:PrintASPath( path )
		for x=1,#path do
			local txt = "NODE->" .. tostring( path[x] )
			self.Owner:PrintMessage( HUD_PRINTTALK, txt )
		end
	end

end

if (CLIENT) then

	function SWEP:DrawHUD()
		local x = ScrW() * 0.8
		local labelcnt = #self.TestModes
		local sizeperlbl = 20
		local h = labelcnt * sizeperlbl
		local w = ScrW()-x
		local y = ScrH()-h
		surface.SetDrawColor( 50, 50, 50, 200 )
		surface.DrawRect( x, y, w, h )
		for k, v in pairs( self.TestModes ) do
			if (v == self:GetNWString( "mode" )) then
				surface.SetDrawColor( 50, 50, 150, 200 )
				surface.DrawRect( x, y+((k-1)*sizeperlbl), w, sizeperlbl )
			end
			draw.SimpleText( v, "PCText", (x+(w/2)), (y+((k-0.5)*sizeperlbl)), Color(255, 255, 255, 255), 1, 1 )
		end
		surface.SetDrawColor( 50, 50, 50, 255 )
		surface.DrawLine( x, y, x, y+h )
		surface.DrawLine( x, y, x+w, y )
	end

end